<?php
/**
 * 单表操作类
 *
 * @category     Shuxun Cms
 * @date         2015年10月5日
 * @author       Shuxun Team <kaiping.jiang@scshux.com>
 * @file         SModel.php
 */
namespace  Scshux\Mvc;
use Phalcon\Mvc\User\Plugin;
use Phalcon\Di;
use Phalcon\Di\FactoryDefault;
class SModel extends Plugin
{
	/**
	 * 数据库操作对象
	 * @var \Phalcon\Db\Adapter\Pdo\Mysql
	 */
	private $db = NULL;

	private $lastError = null;

    /**
     * 数据表名称
     * @var string
     */
	private $tableName = '';

	private $tablePre  = '';

	/**
	 * 要更新的表数据,key:对应表字段; value:数据;
	 * @var array
	 */
	private $tableData = array();

	private $fetchType = \PDO::FETCH_OBJ;

	private  $debug   = false;


	/**
	 * @brief 构造函数,创建数据库对象
	 * @param string $tableName 表名称(当多表操作时以逗号分隔,如：user,goods);
	*/
	public function __construct($tableName,$prefix=false)
	{
		$di        = Di::getDefault();
		$this->db  = $di->get('db');
		$config    = $di->get('config');

		if($prefix === false){
			$this->tablePre  = isset($config->database->prefix) ? $config->database->prefix : '';
		}else{
			$this->tablePre = '';
		}

		if($config->debug){
			$this->debug = true;
		}

		//多表处理
		if(stripos($tableName,','))
		{
			$tables = explode(',',$tableName);
			foreach($tables as $val)
			{
				if($this->tableName != '')
					$this->tableName .= ',';

				$this->tableName .= $this->tablePre.trim($val);
			}
		}
		//单表处理
		else
		{
			$this->tableName = $this->tablePre.$tableName;
		}
	}

	/**
	 * @brief 设置要更新的表数据
	 * @param array $data key:字段名; value:字段值;
	 * @param bool $safe 如果是true将不检查字段直接保存
	 */
	public function setData($data,$safe=false)
	{
		if(is_array($data)){
			if(!$safe){
				$fileds = $this->getFileds();
				foreach ($data as $filed => $value)
				{
					if(!in_array($filed, $fileds)){
						unset($data[$filed]);
					}
				}
			}
			$this->tableData = $data;
			return true;
		}
		else{
			return false;
		}
	}

	/**
	 * 更新
	 * @param  $where
	 * @param  $data
	 */
	public function  updateBySql($where,$data)
	{
		$sql = 'UPDATE '.$this->tableName.' SET '.$data.' WHERE '.$where;
		return $this->db->execute($sql);
	}


	/**
	 * @brief 更新
	 * @param  string $where 更新条件
	 * @param  array  $except 非普通数据形式(key值)
	 * @return int or bool int:影响的条数; bool:false错误
	 */
	public function update($where,$except=array())
	{
		$except = is_array($except) ? $except : array($except);

		//获取更新数据
		$tableObj  = $this->tableData;
		if(empty($tableObj)) return false;

		$updateStr = '';
		$where     = (strtolower($where) == 'all') ? null : ' '.$where;
		foreach ($except as $filed => $value)
		{
			 unset($tableObj[$filed]);
		}

		if(empty($tableObj)) return false;

		try {
			$result =  $this->db->update($this->tableName, array_keys($tableObj), array_values($tableObj),$where);
		} catch (\Exception $e) {
			$this->lastError = $e->getMessage();
			$result = false;
		}
		return $result;
	}

	/**
	 * @brief 添加
	 * @return int or bool int:插入的自动增长值 bool:false错误
	 */
	public function add()
	{
		//获取插入的数据
		$tableObj  = $this->tableData;
		if(empty($tableObj)) return false;
		try {
			$result =  $this->db->insert($this->tableName,array_values($tableObj), array_keys($tableObj));
		} catch (\Exception $e) {
			$this->lastError = $e->getMessage();
			$result = false;
		}
		return $result;
	}

	/**
	 * 获取最后一次错误
	 */
	public  function getLastError()
	{
		return $this->lastError;
	}


	/**
	 * 获取
	 * @return int
	 */
	public  function  getInsertID()
	{
		$result =  $this->db->query('SELECT LAST_INSERT_ID()');
		$row = $result->fetch();
		return intval($row[0]);
	}

	/**
	 * 获取影响的行
	 * @return number
	 */
	public  function  getAffectedRows()
	{
		$result =  $this->db->query('SELECT ROW_COUNT()');
		$row = $result->fetch();
		return intval($row[0]);
	}


	/**
	 * 获取查询的行
	 * @return number
	 */
	public  function  getNumRows()
	{
		$result =  $this->db->query('SELECT FOUND_ROWS()');
		$row = $result->fetch();
		return intval($row[0]);
	}



	/**
	 * @brief 删除
	 * @param string $where 删除条件
	 * @return int or bool int:删除的记录数量 bool:false错误
	 */
	public function del($where)
	{
		$where = (strtolower($where) == 'all') ? '' : null.$where;
		return $this->db->delete($this->tableName,$where);
	}

	/**
	 * @brief 获取单条数据
	 * @param string $where 查询条件
	 * @param array or string $cols 查询字段,支持数组格式,如array('cols1','cols2')
	 * @return array 查询结果
	 */
	public function getObj($where = false,$cols = '*')
	{
		$result = $this->query($where,$cols,'','',1);
		if(empty($result))
		{
			return array();
		}
		else
		{
			return $result[0];
		}
	}

	/**
	 * @brief 获取多条数据
	 * @param string $where 查询条件
	 * @param array or string $cols 查询字段,支持数组格式,如array('cols1','cols2')
	 * @param array or string $orderBy 排序字段
	 * @param array or string $desc 排列顺序 值: DESC:倒序; ASC:正序;
	 * @param array or int $limit 显示数据条数 默认(500)
	 * @return array 查询结果
	 */
	public function query($where=false,$cols='*',$orderBy=false,$desc='DESC',$limit=50000)
	{
		//字段拼接
		if(is_array($cols))
		{
			$colStr = join(',',$cols);
		}
		else
		{
			$colStr = ($cols=='*' || !$cols) ? '*' : $cols;
		}

		$sql = 'SELECT '.$colStr.' FROM '.$this->tableName;

		//条件拼接
		if($where != false) $sql.=' WHERE '.$where;

		//排序拼接
		if($orderBy != false)
		{
			$sql.= ' ORDER BY '.$orderBy;
			$sql.= (strtoupper($desc) == 'DESC') ? ' DESC ':' ASC ';
		}

		//条数拼接
		if($limit != 'all')
		{
			if(is_int($limit)){
				$limit = intval($limit);
				$limit = $limit ? $limit : 500;
			}
			$sql.=' limit ' . $limit;
		}

		//$sql = preg_replace("/{{(.*)}}/is", $this->tablePre."$1", $sql);
		if($this->debug){
			FactoryDefault::getDefault()->get('logger')->info($sql);
		}
		
		$result =  $this->db->query($sql);
		
		$result->setFetchMode($this->fetchType);
		return $result->fetchAll();
	}

	public  function  setFetchMode($fecthMode)
	{
		$this->fetchType = $fecthMode;
	}

	/**
	 * 获取当前表的字段
	 */
	protected  function  getFileds()
	{
		$result = $this->db->query('DESC '.$this->tableName);
		$result->setFetchMode(\PDO::FETCH_ASSOC);
		$fileds =  $result->fetchAll();
		$newFileds = array();
		foreach ($fileds as $key=>$filed)
		{
			$newFileds[] = $filed['Field'];
		}
		return $newFileds;
	}
}